#!/usr/bin/env node
/**
 * 脚手架的构建过程
 * 1、初始化脚手架项目文件
 * 2、创建脚手架入口文件 index.js
 * 3、创建我们脚手架的模版目录文件夹，并将我们的模版文件放入文件夹中
 * 4、编辑我们的脚手架入口文件
 *    1> 安装并引入inquirer 模块，设置发起人机交互内容
 *    2> 引入fs、path 模块，实现模版目录、文件的读写，目标目录的定义，并将我们的模版文件输出到目标文件中
 *    3> 安装并引入模版引擎文件（可选），如果我们的模版文件是固定的，并不需要写入人机交互的数据内容，那么
 *    可以不使用，如果需要写入，则需要安装模版引擎，并通过模版引擎，在模版文件写入过程中，将我们的交互内容
 *    写入到模版文件中
 */
const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')
const ejs = require('ejs')
const { author } = require('../package.json')
const emailReg = new RegExp(/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/)
let user = author.split(' ')
let username, email = ''
for (let a = 0; a < 2; a++) {
  let item = user[a].replace(/\<|>/g, '')
  if (emailReg.test(item)) {
    email = item
    continue
  } else if (a === 0) {
    username = item
  }
}

module.exports = (...params) => {
  inquirer.prompt([
    {
      type: 'input',
      name: 'name',
      message: '项目名:',
      default: path.basename(process.cwd())
    }, {
      type: 'input',
      name: 'version',
      message: '当前版本号:',
      default: '1.0.0'
    }, {
      type: 'input',
      name: 'username',
      message: 'username:',
      default: username
    }, {
      type: 'input',
      name: 'email',
      message: 'email:',
      default: email
    }
  ])
  .then(answer => {
    // 根据用户回答的信息生成文件
    const answerData = { ...answer }

    // 处理人机交互内容可能出现的异常
    answerData.name = answerData.name || path.basename(process.cwd())
    answerData.version = answerData.version || '1.0.0'
    answerData.username = answerData.username || 'default'
    answerData.email = answerData.email || 'default'

    // 模版目录
    let cadminDirname = __dirname.substr(0, __dirname.toString().lastIndexOf('\\'))
    const TEMP_DIR = path.join(cadminDirname, 'templetes')

    // 目标目录
    const DEST_DIR = process.cwd()

    const readAndWrite = async (_tempdir, _destdir) => {
      // 读取模版目录下的所有文件并将文件输出到目标目录
      fs.readdir(_tempdir, (err, files) => {
        if (err) { throw err }

        // 删除无用的.git文件
        files = files.filter(file => file !== '.git')

        // 遍历根目录文件
        files.forEach(file => {
          let _newtempdir = path.join(_tempdir, file)
          let _newdestdir = path.join(_destdir, file)
          let _stat = fs.lstatSync(_newtempdir)

          // 判断文件类型是否是文件夹
          if (_stat.isDirectory()) {
            // 如果是文件夹判断目标根目录中是否存在该文件夹如果不存在创建该文件夹
            return fs.readdir(_destdir, (errmsg, innerFiles) => {
              if (errmsg) throw errmsg
              if (!innerFiles.includes(file)) {
                fs.mkdirSync(_newdestdir)
              }
              readAndWrite(_newtempdir, _newdestdir)
            })
          }

          // 判断是否是.开头的配置文件如果是直接复制写入
          // 如果是图片文件也是直接复制写入
          let imgExtendedNameCheck = new RegExp(/\*BMP|JPG|JPEG|PNG|GIF$/g)
          let spotConfigFileCheck = new RegExp(/\^.&!.*/g)
          if (imgExtendedNameCheck.test(file.toUpperCase()) || spotConfigFileCheck.test(file)) {
            return fs.writeFileSync(_newdestdir, file)
          }

          // 因为需要将用户信息输入到模版文件中,所以我们需要使用模版引擎ejs
          ejs.renderFile(path.join(_tempdir, file), answerData, (error, result) => {
            if (error) { throw error }
            fs.writeFileSync(_newdestdir, result)
          })
        })
      })
    }
    readAndWrite(TEMP_DIR, DEST_DIR)
  })
}